在Git中,如何『删除』commit?

您所在的位置:网站首页 git commit —amend会修改当前提交的节点号 在Git中,如何『删除』commit?

在Git中,如何『删除』commit?

2023-07-27 10:16| 来源: 网络整理| 查看: 265

在Git中,如何『删除』commit?

本文主要参考 How can I delete a commit in Git? 以及文中的链接 翻译、整理而来。

在Git中,如何『删除』commit? 首先,要搞清楚你是哪种情况,因为『删除』commit 有3种方法,但是每种方法的适用情况不一样。 需要注意的是,这里的『删除』的意思是泛泛的,最终的效果像是『删除』了commit,而commit是否真的从提交的历史记录里删掉,则取决于采用的 git 命令。

顺便说一下,Git-Tower的教程还是不错的,在线教程免费,主题清晰,文章简练,有中英文两个版本,英文不错的,建议读读英文版。教程覆盖不到的地方,可以参考他们提供的FAQ。

注:本文中 『commit』和『提交』的概念一样,但是由于中文『提交』的动词含义较重,所以在『提交』后面有其他描述的,则使用『commit』来代替『提交』。

★ 情况1:恢复到某个旧版本

在这里插入图片描述 直接采用Git-Tower网站中的原图。这种情况是说,你想要将项目的版本恢复到C2版本,在效果上等同于将后面的C3和C4 commit『删除』了。在这种情况下,git reset命令适合你。

$ git reset --hard 0ad5a7a6

此命令是将HEAD分支回退到指定的版本(0ad5a7a6),所有在这个版本(0ad5a7a6)之后的commit都删掉了。使用这个命令(带--hard参数)要慎重,因为如果你的改动从没有提交到仓库中,那么你的改动将无法恢复了。--hard参数是git reset命令的唯一的危险的参数。如果你删除错了,本地未提交的数据就彻底丢失了。如果已经提交到本地仓库中,则可以参考这个链接来恢复数据。

$ git reset --soft 0ad5a7a6

使用--soft参数,会把 0ad5a7a6 之后所有的commit的改动保留在工作目录(Working copy)中,留给你做进一步处理。

git reset命令还是有些危险的,所以需要搞清楚git reset的原理之后再使用。更多git reset的原理介绍,请参考 git官方文档 重置解密。

还有一种更安全的方式,可以保持HEAD分支不动,就是使用git checkout命令将某个旧版本拉到一个新分支中。

$ git checkout -b old-project-state 0ad5a7a6

-b参数用来创建一个新分支old-project-state。git checkout切换到old-project-state分之后,就恢复到了旧版本。

注1:HEAD是指向当前所在的分支的最后一次提交,也是下一次提交的父节点。可以看做是当前分支的别名,例如HEAD指向master分支,则也可以用『HEAD分支』来指代master分支。 注2:『HEAD分支』在Git-Tower中的原文为『HEAD branch』。

★ 情况2:撤销某一个commit

在这里插入图片描述

如上图所示,撤销 C2 这个commit,但是保留C3、C4的改动。在这种情况下,可以使用git revert命令。 git revert命令并不会删除C2,而是创建一个新的commit,将C2中的改动再改回去。如下图所示。

在这个例子中,在revert之前是没有C4 commit的,假设C2的commit id为 0ad5a7a6,执行git revert 0ad5a7a6则会创建C4 commit。

在这里插入图片描述

★ 情况3:从提交历史中删掉一个commit

如下图所示,从提交历史中删除C2 commit,而保留C3、C4的改动。

在这里插入图片描述 出现这种情况的时候,可能是因为我不小心提交了关键的、不应该公开的信息(例如密码、私钥),我需要从历史中把commit删掉。此时,就需要用到最强大也最危险的工具git rebase -i。

例如,我有3次提交,使用git log命令显示如下:

$ git log --pretty=format:"%h %s" HEAD~3..HEAD a5f4a0d added cat-file 310154e updated README formatting and added blame f7f3f6d changed my name a bit

我想删除『a5f4a0d added cat-file』这个提交。

执行git rebase -i HEAD~3命令,结果如下:

$ git rebase -i HEAD~3 pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file

删除commit a5f4a0d,就是把『pick a5f4a0d added cat-file』这一行删掉。如下,

pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame

保存并退出编辑器,git就把 commit a5f4a0d删掉了。

需要说明的是,如果只是删掉『a5f4a0d added cat-file』,不需要使用HEAD~3,使用HEAD~1就行,因为commit a5f4a0d是最后一个提交,是HEAD指向的提交。

扩展:

如果只是想修改历史记录里的邮箱、名字,则可以用git filter-branch并配合--commit-filter来使用。例如,修改邮箱和名字的命令,将所有原来邮箱是schacon@localhost的commit,都把邮箱改为[email protected],名字改为Scott Chacon。邮箱不是schacon@localhost的commit则邮箱保持不变。但是,所有受影响的commit的SHA-1校验都会变化。命令如下:

$ git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; then GIT_AUTHOR_NAME="Scott Chacon"; GIT_AUTHOR_EMAIL="[email protected]"; git commit-tree "$@"; else git commit-tree "$@"; fi' HEAD ★ 参考 How can I delete a commit in Git?How can I restore a previous version of my project?How can I undo an older commit?关于HEAD的说明:https://git-scm.com/book/zh/v2/Git-分支-分支简介撤销操作:https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/undoing-things重置解密:https://git-scm.com/book/zh/v2/Git-工具-重置揭密重写历史:https://git-scm.com/book/zh/v2/Git-工具-重写历史


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3